// chrome.scripting API 降级适配，兼容仅支持 Manifest V2 的浏览器（如部分360内核）
(function () {
  if (typeof chrome === 'undefined') {
    return;
  }

  if (chrome.scripting && typeof chrome.scripting.executeScript === 'function') {
    return;
  }

  function normalizeFrameId(target) {
    if (!target) {
      return undefined;
    }
    if (Array.isArray(target.frameIds) && target.frameIds.length > 0) {
      return target.frameIds[0];
    }
    if (typeof target.frameId === 'number') {
      return target.frameId;
    }
    return undefined;
  }

  function promisifyExecuteScript(tabId, details, frameId) {
    const executeDetails = Object.assign({}, details);
    if (typeof frameId === 'number') {
      executeDetails.frameId = frameId;
    }

    return new Promise((resolve, reject) => {
      chrome.tabs.executeScript(tabId, executeDetails, (results) => {
        const lastError = chrome.runtime.lastError;
        if (lastError) {
          reject(new Error(lastError.message));
          return;
        }

        const formatted = (results || []).map((value) => ({
          frameId: typeof frameId === 'number' ? frameId : 0,
          result: value
        }));
        resolve(formatted);
      });
    });
  }

  function buildCodeFromFunc(func, args) {
    if (typeof func !== 'function') {
      throw new Error('chrome.scripting.executeScript 需要 func 为函数或提供 files');
    }

    let serializedArgs = '[]';
    try {
      serializedArgs = JSON.stringify(Array.isArray(args) ? args : []);
    } catch (error) {
      throw new Error('chrome.scripting.executeScript 参数必须可序列化: ' + error.message);
    }

    return `(${func.toString()}).apply(null, ${serializedArgs});`;
  }

  const scripting = chrome.scripting || {};

  scripting.executeScript = function (options = {}) {
      const { target, files, func, args, injectImmediately } = options;
      if (!target || typeof target.tabId !== 'number') {
        return Promise.reject(new Error('chrome.scripting.executeScript 需要提供 target.tabId'));
      }

      if ((!files || files.length === 0) && typeof func !== 'function') {
        return Promise.reject(new Error('chrome.scripting.executeScript 至少需要 files 或 func 之一'));
      }

      const frameId = normalizeFrameId(target);
      const runAt = injectImmediately ? 'document_start' : undefined;

      const executeQueue = [];

      if (Array.isArray(files)) {
        files.forEach((file) => {
          executeQueue.push(() => {
            const details = { file };
            if (runAt) {
              details.runAt = runAt;
            }
            return promisifyExecuteScript(target.tabId, details, frameId);
          });
        });
      }

      if (typeof func === 'function') {
        executeQueue.push(() => {
          const details = { code: buildCodeFromFunc(func, args) };
          if (runAt) {
            details.runAt = runAt;
          }
          return promisifyExecuteScript(target.tabId, details, frameId);
        });
      }

      return executeQueue.reduce((prevPromise, task) => {
        return prevPromise.then((accumulated) => task().then((results) => {
          return accumulated.concat(results);
        }));
      }, Promise.resolve([]));
    };

  chrome.scripting = scripting;
})();
